scrumBoardColumnWrapperProto = {
    defaultType : 'scrumcolumn'
	,layout : 'column'
    ,autoScroll : true
    ,closable: false
    ,initComponent : function(){
        scrumBoardColumnWrapper.superclass.initComponent.call(this);
        this.addEvents({
            validatedrop:true,
            beforedragover:true,
            dragover:true,
            beforedrop:true,
            drop:true
        });
        this.addListener('drop', this.updateTicketState, this);
    }

    , reloadAllTickets : function()
    {
        filters = sweatShop.getFilters();
        for (col in this.items.items)
        {
            aColumn = this.items.items[col];
            if(!aColumn.reloadTickets) continue;
            aColumn.reloadTickets(filters);
        }
    }
    ,initEvents : function(){
        scrumBoardColumnWrapper.superclass.initEvents.call(this);
        this.dd = new scrumBoardColumnWrapper.DropZone(this, this.dropConfig);
    }

    ,beforeDestroy : function() {
        if(this.dd){
            this.dd.unreg();
        }
        scrumBoardColumnWrapper.superclass.beforeDestroy.call(this);
    }

	, updateTicketState : function(e)
    {
        console.log(e);
        var ticket = Ext.getCmp(e.source.id);

        ticket.doLayout(false);
        this.doLayout(false);
        ticket.setScrumState(e.column.scrumState);
        if(e.column.promptForHours || sweatShop.autoPromptHours)
            ticket.openBookHoursPrompt();
    }
};
scrumBoardColumnWrapper = Ext.extend(Ext.Panel, scrumBoardColumnWrapperProto);

scrumBoardColumnWrapper.DropZone = Ext.extend(Ext.dd.DropTarget, {
    ddGroup :  'scrumboard'
    ,constructor : function(board, cfg){
        this.board = board;
        Ext.dd.ScrollManager.register(board.body);
        scrumBoardColumnWrapper.DropZone.superclass.constructor.call(this, board.bwrap.dom, cfg);
        board.body.ddScrollConfig = this.ddScrollConfig;
    },

    ddScrollConfig : {
        vthresh: 50,
        hthresh: -1,
        animate: true,
        increment: 200
    },

    createEvent : function(dd, e, data, col, c, pos){
        return {
            board: this.board,
            panel: data.panel,
            columnIndex: col,
            column: c,
            position: pos,
            data: data,
            source: dd,
            rawEvent: e,
            status: this.dropAllowed
        };
    },

    notifyOver : function(dd, e, data){
        var xy = e.getXY(), board = this.board, px = dd.proxy;

        // case column widths
        if(!this.grid){
            this.grid = this.getGrid();
        }

        // handle case scroll where scrollbars appear during drag
        var cw = board.body.dom.clientWidth;
        if(!this.lastCW){
            this.lastCW = cw;
        }else if(this.lastCW != cw){
            this.lastCW = cw;
            board.doLayout();
            this.grid = this.getGrid();
        }

        // determine column
        var col = 0, xs = this.grid.columnX, cmatch = false;
        for(var len = xs.length; col < len; col++){
            if(xy[0] < (xs[col].x + xs[col].w)){
                cmatch = true;
                break;
            }
        }
        // no match, fix last index
        if(!cmatch){
            col--;
        }

        // find insert position
        var p, match = false, pos = 0,
            c = board.items.itemAt(col),
            items = c.items.items, overSelf = false;

        for(var len = items.length; pos < len; pos++){
            p = items[pos];
            var h = p.el.getHeight();
            if(h === 0){
                overSelf = true;
            }
            else if((p.el.getY()+(h/2)) > xy[1]){
                match = true;
                break;
            }
        }

        pos = (match && p ? pos : c.items.getCount()) + (overSelf ? -1 : 0);
        var overEvent = this.createEvent(dd, e, data, col, c, pos);

        if(board.fireEvent('validatedrop', overEvent) !== false &&
           board.fireEvent('beforedragover', overEvent) !== false){

            // make sure proxy width is fluid
            px.getProxy().setWidth('auto');

            if(p){
                px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);
            }else{
                px.moveProxy(c.el.dom, null);
            }

            this.lastPos = {c: c, col: col, p: overSelf || (match && p) ? pos : false};
            this.scrollPos = board.body.getScroll();

            board.fireEvent('dragover', overEvent);

            return overEvent.status;
        }else{
            return overEvent.status;
        }

    },

    notifyOut : function(){
        delete this.grid;
    },

    notifyDrop : function(dd, e, data){
        delete this.grid;
        if(!this.lastPos){
            return;
        }
        var c = this.lastPos.c,
            col = this.lastPos.col,
            pos = this.lastPos.p,
            panel = dd.panel,
            dropEvent = this.createEvent(dd, e, data, col, c,
                pos !== false ? pos : c.items.getCount());

        if(this.board.fireEvent('validatedrop', dropEvent) !== false &&
           this.board.fireEvent('beforedrop', dropEvent) !== false){

            dd.proxy.getProxy().remove();
            panel.el.dom.parentNode.removeChild(dd.panel.el.dom);

            if(pos !== false){
                c.insert(pos, panel);
            }else{
                c.add(panel);
            }

            c.doLayout();

            this.board.fireEvent('drop', dropEvent);

            // scroll position is lost on drop, fix it
            var st = this.scrollPos.top;
            if(st){
                var d = this.board.body.dom;
                setTimeout(function(){
                    d.scrollTop = st;
                }, 10);
            }

        }
        delete this.lastPos;
    },

    // internal cache of body and column coords
    getGrid : function(){
        var box = this.board.bwrap.getBox();
        box.columnX = [];
        this.board.items.each(function(c){
             box.columnX.push({x: c.el.getX(), w: c.el.getWidth()});
        });
        return box;
    },

    // unregister the dropzone from ScrollManager
    unreg: function() {
        Ext.dd.ScrollManager.unregister(this.board.body);
        this.board.DropZone.superclass.unreg.call(this);
    }
});

scrumBoardProto = {
    initComponent : function(){
        this.items = this.contentItems;
        scrumBoard.superclass.initComponent.call(this);
        //sweatShop.globals.bindHandlers(this.title, this.getHandlers());
    }
    ,title: 'Scrum board'
	,tools:[
        {
            id: 'refresh'
            , handler: function(event, toolEl, panel){
                panel.reloadAllTickets();
            }, qtip: 'Reload tickets'
        }
    ]
	,defaults:{
		columnWidth : .33
        ,defaults:{
            collapsed: true
        }
	}
	,contentItems: [
		{
			title: 'Waiting'
            , xtype : 'scrumcolumn'
			, scrumState : 2
		},{
			title: 'In progress'
			, xtype : 'scrumcolumn'
            , scrumState : 3
		},{
			title: 'Review'
			, xtype : 'scrumcolumn'
            , scrumState : 4
		}
	]
    , getHandlers : function()
    {
        return {
          scumboarUpdateButton : {fn: this.reloadAllTickets, scope: this}
        };
    }
};
scrumBoard = Ext.extend(scrumBoardColumnWrapper, scrumBoardProto);
Ext.reg('scrumboard', scrumBoard);

backLogProto = {
	title: 'Backlog'
    ,backlogCol : null
    ,initComponent : function(){
        this.items = this.contentItems;
        backLog.superclass.initComponent.call(this);
        this.backlogCol = this.items.items[0];
    }
    ,tools:[
        {
            id: 'refresh'
            , handler: function(event, toolEl, panel){
                panel.reloadAllTickets();
            }, qtip: 'Reload tickets'
        }
    ]
	,contentItems : [{
		title: ''
		, scrumState : 1
	}]
	,defaults: {
		colWidth: 1
		,defaults: {
			collapsed: true
		}
	}
    , addTicket : function(ticketInfo)
    {
        this.backlogCol.addTicket(ticketInfo);
        this.backlogCol.doLayout();
    }
    , openTicketEditor : function ()
    {
        new newTicketEditor().show();
    }
};
backLog = Ext.extend(scrumBoardColumnWrapper, backLogProto);
Ext.reg('backlog', backLog);

doneLogProto = {
	title: 'Done'
    ,initComponent : function(){
        this.items = this.contentItems;
        doneLog.superclass.initComponent.call(this);
    }
    ,tools:[
        {
            id: 'refresh'
            , handler: function(event, toolEl, panel){
                panel.reloadAllTickets();
            }, qtip: 'Reload tickets'
        }
    ]
	,contentItems : [{
		title: ''
		, scrumState : 9
        , promptForHours : true
        , colWidth : 1
        , autoScroll : true
        , defaults : {
            collapsed : true
        }
	}]
};
doneLog = Ext.extend(scrumBoardColumnWrapper, doneLogProto);
Ext.reg('donelog', doneLog);
